# -*- coding: utf-8 -*-

# -------------------------------
# Author    : linlingwei
# Email     : 951035650@qq.com
# File Name : blendShape_editor.py
# Date      : 2018/9/13
# IDE       : PyCharm
# Version   : 1.0.1
# -------------------------------


__author__ = "lin lingwei"
__version__ = "1.1.5"
import traceback
import maya.cmds as mc

from configs.constants.global_constant import *

import scripts.commonCmds as cCore
import editors.editor as editor
reload(editor)
import scripts.deformerCmds as dCore
reload(dCore)


__mayaVersion__ = mc.about(v=True)

class BlendShapeEditor(editor.Editor):
    def __init__(self):
        super(BlendShapeEditor,self).__init__()
        self.load_geo = None
        self.load_bls = None
        self.blendShape = None
        self.tree = None
        self.search = None
        self.output = None
        self.tgt_slider = None


    def editor(self):
        winName = "BlendShapeEditor"
        self.isExist(winName)

        wintitle = " - BlendShape Eidtor - V{}".format(__version__)
        image = os.path.join(gIconPath,"mainLogo.svg")

        _win = mc.window(winName, t=wintitle, wh=[400, 600], s=False, mxb=False, te=100,
                         # iconName=image,
                         )
        # ---------------
        self.mainMenu()
        self.mainLayout()
        # ---------------

        mc.showWindow(_win)

    def mainMenu(self):
        mbl = mc.menuBarLayout(bgc=self.rgbConvert(118, 137, 143))
        mc.menu(l='File')

        mc.menuItem(l='Setting ... ', )

        mc.setParent('..')

        mc.menu(l='Display')

        mc.menuItem(l='Setting ... ', )

        mc.setParent('..')

        mc.menu(l='About')

        mc.menuItem(l='Setting ... ', )

        mc.setParent('..')

        return mbl

    def mainLayout(self):
        form = mc.formLayout(bgc=self.rgbConvert(157, 181, 193))

        coulmn = self.bls_coulmn()
        tree = self.bls_tree()
        cmdslist = self.bls_cmdsList()
        ver = self.bls_version()

        mc.setParent('..')

        mc.formLayout(form, edit=True,
                      attachForm=[(coulmn, 'top', 5), (coulmn, 'left', 5), (coulmn, 'right', 5),
                                  (tree, 'left', 5),
                                  (cmdslist, 'right', 5),
                                  (ver, 'bottom', 5), (ver, 'right', 5), (ver, 'left', 5)],
                      attachControl=[(tree, 'top', 5, coulmn),
                                     (cmdslist, 'top', 5, coulmn),
                                     (tree, 'bottom', 5, ver), (cmdslist, 'bottom', 5, ver),
                                     ],

                      attachPosition=[(tree, 'right', 5, 75), (cmdslist, 'left', 0, 75)],
                      # attachNone=(b2, 'top')
                      )

        return form

    def bls_coulmn(self):
        rh = 25
        bh = 22

        bcolor = self.rgbConvert(157, 181, 193)
        scolor = self.rgbConvert(12, 141, 170)

        form = mc.formLayout(bgc=bcolor)

        georow = mc.rowLayout(nc=10, bgc=self.rgbConvert(118, 137, 143))
        mc.text(' Geometry      => ', font="fixedWidthFont")
        geo = mc.textField(w=158, bgc=bcolor,ed=False)
        self.load_geo = geo
        mc.setParent('..')

        blsrow = mc.rowLayout(nc=10, bgc=self.rgbConvert(118, 137, 143))
        mc.text(' BlendShape    => ', font="fixedWidthFont")
        bls = mc.textField(w=158, h=bh, bgc=bcolor, ed=False)
        self.load_bls = bls
        mc.setParent('..')

        b3 = mc.button(l="  Load  ... ", h=bh, w=95,
                       bgc=self.rgbConvert(87, 152, 184),
                       c=lambda *args: self.btn_load()
                       )
        mc.setParent('..')

        mc.formLayout(form, edit=True,
                      attachForm=[(georow, 'top', 0), (georow, 'left', 0),
                                  (blsrow, 'bottom', 0), (blsrow, 'left', 0),
                                  (b3, 'right', 0), (b3, 'top', 0), (b3, 'bottom', 0),
                                  ],
                      attachControl=[(georow, 'right', 5, b3),
                                     (blsrow, 'right', 5, b3),
                                     (georow, 'bottom', 5, blsrow),
                                     ],
                      )

        return form

    def bls_tree(self):

        tree_form= mc.formLayout()
        if int(__mayaVersion__) > 2016:
            search = mc.textField(sf=True)
        else:
            search = mc.textField()
        mc.textField(search, e=True, h=23, bgc=self.rgbConvert(54, 56, 58))
        # search = mc.button()
        self.search = search
        tree = mc.treeView(bgc=self.rgbConvert(54, 56, 58), h=440, adr=False,
                           scc = lambda *args:self.tree_selectCmd(),
                           # irc = lambda *args:self.btn_rename()
                           )
        # tree = mc.button()
        mc.setParent('..')

        mc.formLayout(tree_form, edit=True,
                      attachForm=[(search, 'top', 0), (search, 'left', 0), (search, 'right', 0),
                                  (tree, 'bottom', 0), (tree, 'right', 0), (tree, 'left', 0)],
                      attachControl=[(tree, 'top', 0, search),
                                     # (tree, 'bottom', 5, ver), (cmdslist, 'bottom', 5, ver),
                                     ],

                      attachPosition=[(tree, 'bottom', 0, 75), (search, 'top', 0, 75)],
                      attachNone=[(search, 'top'),(tree, 'bottom'),]
                      )
        self.tree = tree
        return tree_form

    def bls_cmdsList(self):
        coulmn = mc.columnLayout(adj=True,
                                 bgc=self.rgbConvert(54, 56, 58))

        tgt_slider = mc.floatSliderGrp(w=90,field=True,cw2=[35,2],fmx=1,fmn=0,max=1,min=0,
                                       cc = lambda *args:self.sliderChangeCmd(),
                                       s=0.001)
        self.tgt_slider = tgt_slider
        mc.button("refresh",l="Refresh",c = lambda *args:self.refresh_tree())
        mc.button("remove",l="Remove",c = lambda *args:self.btn_remove())
        mc.button("append",l="Append",c = lambda *args:self.btn_append())
        mc.button("rename",l="Rename",c = lambda *args:self.btn_rename())
        mc.button("replace",l = "Replace", c = lambda *args:self.btn_replace())
        mc.button("mirror",l="Mirror",c = lambda *args:self.btn_mirror())
        mc.button("selectTgt",l="Select Tgt",c = lambda *args:self.btn_selectTgt())
        btn = mc.button(bgc=self.rgbConvert(220, 185, 103), w=90)

        mc.setParent('..')

        return coulmn

    def bls_version(self):
        column = mc.columnLayout(adj=True,
                                 bgc=self.rgbConvert(54, 56, 58))

        out = mc.textField(bgc=self.rgbConvert(40, 40, 40), ed=False, pht=' ...',
                           )
        self.output = out
        self.copyright()
        return column

    def btn_load(self):
        try:
            self.refresh_geo()
            self.refresh_bls()
            self.refresh_tree()
        except:
            traceback.print_exc()
        return

    def output_info(self,strs):
        bgc = self.rgbConvert(220, 185, 103)
        mc.textField(self.output,e=True,tx=strs)
        return

    def output_waring(self,strs):
        bgc = self.rgbConvert(255, 237, 97)
        mc.textField(self.output,e=True,tx="Waring : {}".format(strs),bgc=bgc)
        return
    def output_error(self,strs):
        bgc = self.rgbConvert(234, 85, 41)
        mc.textField(self.output,e=True,tx=strs,bgc=bgc)
        return

    def refresh_geo(self):

        sel = mc.ls(sl=True)

        if len(sel) > 0:
            mc.textField(self.load_geo, e=True, tx=sel[0])
        else:
            self.output_waring("Not selected.")

        return

    def refresh_bls(self):

        geo_tx = mc.textField(self.load_geo,q=True,tx=True)
        if geo_tx:
            bls = dCore.findRelatedDeformer(geo_tx,"blendShape")
            if bls:
                mc.textField(self.load_bls,e=True,tx = bls[0])
                self.blendShape = bls[0]
            else:
                self.output_waring("Selected geometry not blendShape.")
        return
    def refresh_tree(self):
        # print self.blendShape
        if not self.blendShape:
            return
        mc.treeView(self.tree,e=True,ra=True)
        allItems = dCore.getBlendShapeIndexDict(self.blendShape)
        for index in allItems:
            self.tree_add(allItems[index])
        if allItems:
            mc.treeView(self.tree,e=True,si=(allItems[0],1))
            mc.floatSliderGrp(self.tgt_slider,e=True,v=mc.getAttr("{}.{}".format(self.blendShape,allItems[0])))
        return

    def tree_add(self,name,):
        mc.treeView(self.tree, e=True, addItem=(name, ""))
        mc.treeView(self.tree, e=True, ornament=(name, 1,0,3))
        mc.treeView(self.tree, e=True, ornamentColor = (name,0.5,1,0.1))
        return

    def tree_selectCmd(self):
        selItem = mc.treeView(self.tree,q=True,si=True)
        if selItem:
            tgt_value = mc.getAttr("{}.{}".format(self.blendShape,selItem[0]))
            mc.floatSliderGrp(self.tgt_slider,e=True,v=tgt_value)
            return
    def sliderChangeCmd(self):
        selItem = mc.treeView(self.tree,q=True,si=True)
        if selItem:
            value = mc.floatSliderGrp(self.tgt_slider,q=True,v=True)
            mc.setAttr("{}.{}".format(self.blendShape,selItem[0]),value)
            return

    def btn_remove(self):
        selItem = mc.treeView(self.tree,q=True,si=True)
        if selItem:
            dCore.blendShapeRemoveItem(self.blendShape,selItem[0])
        self.refresh_tree()
        return

    def btn_append(self):
        sel = mc.ls(sl=True)
        if sel:
            dCore.blendShapeAppendTgt(self.blendShape,sel[0])
            self.refresh_tree()
        return
    def btn_rename(self):
        selItem = mc.treeView(self.tree,q=True,si=True)
        if selItem:
            result = mc.promptDialog(
                title='Rename Object',
                message='Enter Name:',
                button=['OK', 'Cancel'],
                defaultButton='OK',
                cancelButton='Cancel',
                dismissString='Cancel')
            if result == 'OK':
                newName = mc.promptDialog(query=True, text=True)
                dCore.blendShapeRenameTgt(self.blendShape,selItem[0],newName)
                self.refresh_tree()
        return
    def btn_replace(self):
        selItem = mc.treeView(self.tree,q=True,si=True)
        sel = mc.ls(sl=True)
        if selItem and sel:
            dCore.blendShapeReplaceTgt(self.blendShape,selItem[0],sel[0])
        return
    def btn_selectTgt(self):
        selItem = mc.treeView(self.tree,q=True,si=True)
        if selItem:
            itemTgt = dCore.getBlendShapeItemTgt(self.blendShape,selItem[0])
            if itemTgt:
                mc.select(itemTgt)
        return
    def btn_mirror(self):
        selItem = mc.treeView(self.tree,q=True,si=True)
        if len(selItem) > 1:
            baseShape = mc.blendShape(self.blendShape,q=True,g=True)[0]
            baseGeo = mc.listRelatives(baseShape,p=True)[0]
            orig = cCore.findRelateOrigShape(baseGeo)
            sItem = dCore.getBlendShapeItemTgt(self.blendShape,selItem[0])
            tItem = dCore.getBlendShapeItemTgt(self.blendShape,selItem[1])
            print sItem
            print selItem
            if tItem:
                dCore.shapeMirror(orig,sItem,tItem)
            else:
                newTgt = dCore.shapeMirror(orig, sItem)
                dCore.blendShapeReplaceTgt(self.blendShape,selItem[1],newTgt)
                
                #bbmin = mc.getAttr("{}.bbnx".format(sItem))
                #bbmax = mc.getAttr("{}.bbxx".format(sItem))

                #offest = abs(bbmin) + abs(bbmax)
                #mc.setAttr("{}.tx".format(newTgt), (offest + (offest / 10)))
            
            self.output_info("{} => Mirror success.".format(selItem[1]))
        return

def showEditor():
    BlendShapeEditor().editor()

    return
if __name__ == '__main__':
    pass